/**
 * 假设有一个叫 EffectModule 的类
 * class EffectModule {}
 * 这个对象上的方法只可能有两种类型签名:
 * asyncMethod<T, U>(input: Promise<T>): Promise<Action<U>>
 * syncMethod<T, U>(action: Action<T>): Action<U>
 * 这个对象上还可能有一些任意的非函数属性：
 * count = 1;
 * message = "hello!";
 * 现在有一个叫 connect 的函数，它接受 EffectModule 实例，将它变成另一个对象
 * 这个对象上只有EffectModule 的同名方法，但是方法的类型签名被改变了：
 * asyncMethod<T, U>(input: Promise<T>): Promise<Action<U>>  变成了
 * asyncMethod<T, U>(input: T): Action<U> 
 * syncMethod<T, U>(action: Action<T>): Action<U>  变成了
 * syncMethod<T, U>(action: T): Action<U>
 * 例子:如下
 */

interface Action<T> {
  payload?: T;
  type: string;
}

class EffectModule {
  count = 1;
  message = "hello!";

  delay(input: Promise<number>) {
    return input.then(i => ({
      payload: `hello ${i}!`,
      type: 'delay'
    }));
  }

  setMessage(action: Action<Date>) {
    return {
      payload: action.payload!.getMilliseconds(),
      type: "set-message"
    };
  }
}

// 修改 Connect 的类型，让 connected 的类型变成预期的类型
type Connect = (module: EffectModule) => any;
// 把第27行any替换成你的代码

const connect: Connect = m => ({
  delay: (input: number) => ({
    type: 'delay',
    payload: `hello 2`
  }),
  setMessage: (input: Date) => ({
    type: "set-message",
    payload: input.getMilliseconds()
  })
});

type Connected = {
  delay(input: number): Action<string>;
  setMessage(action: Date): Action<number>;
};

export const connected: Connected = connect(new EffectModule());
